﻿import sys

# 页表常量定义
PAGE_SIZE = 4096  # 4KB页大小
ENTRIES_PER_TABLE = 512  # 每个页表的条目数（2^9）

# 虚拟地址位域划分（48位）
P4 = 12
P3 = 20
P2 = 28
P1 = 36

# 页表项标志位
PRESENT = 1 << 0
WRITABLE = 1 << 1
USER_ACCESS = 1 << 2
PWT = 1 << 3  # Page Write Through
PCD = 1 << 4  # Page Cache Disable
ACCESSED = 1 << 5
DIRTY = 1 << 6
PAGE_SIZE_FLAG = 1 << 7  # 用于大页
Reverse = 1 << 11
NO_EXECUTE = 1 << 63  # XD位


class PTE:
    def __init__(self, addr: int, flag: int, ne: int = NO_EXECUTE):
        self.PFN = addr << 12
        self.flags = flag
        self.NE = ne

    def __int__(self) -> int:
        return self.PFN | self.flags | self.NE


class PageTable:
    def __init__(self):
        self.entries = [None] * ENTRIES_PER_TABLE

    def __getitem__(self, index: int) -> PTE:
        return self.entries[index]

    def __setitem__(self, index: int, value: PTE):
        self.entries[index] = value


class PageDirectory:
    def __init__(self, has_opt: bool = False):
        self.base = 0
        self.items: list[PageTable] | None = None
        self.has_opt = has_opt

    def map_page(self, vaddr: int, paddr: int, access: int, size: int) -> None:
        if self.items is None:
            self.items = [PageTable()*4]
        if self.has_opt:
            pass
        else:
            match size:
                case 0x1000: pass
                case 0x200000: pass
                case 0x40000000:
                    temp = PTE(paddr, (access | PRESENT | PAGE_SIZE_FLAG))
                case _: raise Exception("Invalid page size")


def main():
    while True:
        page_message = input("请输入页表信息：")
        if page_message == 'exit':
            exit()
        page_message = page_message.split(',')
        result = 0
        for i in page_message:
            if i[0] == '0':
                result |= (int(i, 16) << 12)
            else:
                match i:
                    case 'NotExecute': result |= NO_EXECUTE
                    case 'Present': result |= PRESENT
                    case 'Writable': result |= WRITABLE
                    case 'UserAccess': result |= USER_ACCESS
                    case 'PWT': result |= PWT
                    case 'PCD': result |= PCD
                    case 'Accessed': result |= ACCESSED
                    case 'Dirty': result |= DIRTY
                    case 'PageSize': result |= PAGE_SIZE_FLAG
                    case 'Reverse': result |= Reverse
                    case _: raise Exception("Invalid flag")
        print(hex(result))


if __name__ == '__main__':
    main()
